package net.jdm.domain.entity;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.jdm.common.HashSetExt;
import net.jdm.domain.dependence.ComponentDependence;


public class SystemModel implements Scope{
    private final HashSetExt<Package> packages= new HashSetExt<Package>();
	private final HashSetExt<Component> components=new HashSetExt<Component>();
    private final HashSetExt<Class> classes=new HashSetExt<Class>();
    private String root;
    public SystemModel(String root){
    	this.root=root;
    }
	public Set<ComponentDependence> getDependencesWithinMe() {
		HashSetExt<ComponentDependence> componentDependences = new HashSetExt<ComponentDependence>();
		for (Component component : components) {
			Set<Component> efferentComponents = component.getEfferents();
			for(Component efferentComponent:efferentComponents){
				if(components.contains(efferentComponent)){
					componentDependences.add(new ComponentDependence(component, efferentComponent));
				}
			}
		}
		return componentDependences;
	}
	public String getName(){
       return root;
	}
	public Collection<List<? extends ContainerNode>> getCyclesWithinMe() {
		Map<Set<Component>, List<? extends ContainerNode>> cyclesMap = new HashMap<Set<Component>, List<? extends ContainerNode>>();
		for (Component component : components) {
			Collection<List<Component>> cycles = component.getOuterComponentCycles();
			for (List<Component> cycle : cycles) {
				if (!cycle.isEmpty()) {
					Set<Component> key = new HashSet<Component>();// NOPMD
					key.addAll(cycle);
					cyclesMap.put(key, cycle);
				}
			}
		}
		return cyclesMap.values();
	}
	public HashSetExt<Component> getComponents() {
		return components;
	}
	public Component getComponent(String name) {
		 return this.components.getByHashCode(name.hashCode());
	}
	public HashSetExt<Package> getPackages() {
		return packages;
	}
	public Package getPackage(String name){
	       return this.packages.getByHashCode(name.hashCode());
	}
	public HashSetExt<Class> getClasses() {
		return classes;
	}
	public Class getClass(String className) {
		return getClasses().getByHashCode(className.hashCode());
	}

	public void reset() {
		components.clear();
		packages.clear();
		classes.clear();
	}
}
